// ## 2023/10/20 # 黑店小小二 # 移植大浪mod新特技 ##

namespace 大浪新特技 {
	class Main {
    pk::random random(pk::rand());

    array<string> 死者台词 =
    {
      "可恶..真是太荒唐了..",
      "我的武运到此为止了么.."
    };

    array<int> unit_list_id;

    Main()
    {
    	pk::bind(111, pk::trigger111_t(onForceBegin));
    	pk::bind(175, pk::trigger175_t(onUnitDestroy));
    }

    void onForceBegin(pk::force@ force)
    {
    	if (!pk::is_alive(force) or force.get_id() >= 非贼势力_末) return ;
    	func_巧匠(force);
    	func_相邻特技(force);
      func_势力城池(force);
    }

    void onUnitDestroy(pk::unit@ attacker, pk::unit@ target)
    {
      func_收拢(target);
      if (ch::has_skill(attacker, 特技_击虚)) func_击虚(attacker, target);
      if (ch::has_skill(target, 特技_反击)) func_反击(attacker, target);
      if (ch::has_skill(target, 特技_伪退)) func_伪退(attacker, target);
      if (ch::has_skill(attacker, 特技_激昂)) func_激昂(attacker);
      if (ch::has_skill(attacker, 特技_引燃)) func_引燃(attacker, target);
    }

    void func_巧匠(pk::force@ force)
    {
    	for (int i = 0; i < 87; i += 1)
    	{
    		pk::building@ building = pk::get_building(i);
    		if (building !is null and building.get_force_id() == force.get_id())
    		{
    			if (ch::has_skill(building, 特技_巧匠, false))
    			{
    				int value = pk::core::skill_constant_value(特技_巧匠);
    				pk::add_weapon_amount(building, 兵器_枪, value, true);
    				pk::add_weapon_amount(building, 兵器_戟, value, true);
    				pk::add_weapon_amount(building, 兵器_弩, value, true);
    			}
    		}
    	}
    }

    void func_相邻特技(pk::force@ force)
    {
    	pk::list<pk::unit@> unit_list = pk::get_unit_list(force);
    	if (unit_list.count > 0)
    	{
    		for (int i = 0; i < int(unit_list.count); i += 1)
    		{
    			pk::unit@ unit = unit_list[i];
    			if (
              ch::has_skill(unit, 特技_斩将) or 
              ch::has_skill(unit, 特技_毁坏) or 
              ch::has_skill(unit, 特技_纵火) or 
              ch::has_skill(unit, 特技_苦肉) or
              ch::has_skill(unit, 特技_魅惑)
            )
    			{
    				array<pk::point> rings = pk::range(unit.get_pos(), 1, 1);
    				for (int d = 0; d < int(rings.length); d++)
			      {
			        pk::unit@ dst = pk::get_unit(rings[d]);
			        if (dst !is null and dst.get_force_id() != force.get_id())
			        {
			        	func_斩将(force, unit, dst);
			        	func_毁坏(force, unit, dst);
                func_纵火(force, unit, dst);
                func_苦肉(force, unit, dst);
                func_魅惑(force, unit, dst);
			        }
			      }
    			}
    		}
    	}
    }

    void func_斩将(pk::force@ force, pk::unit@ attacker, pk::unit@ target)
    {
    	if (ch::has_skill(attacker, 特技_斩将) and target.status > 0 and pk::rand_bool(pk::core::skill_constant_value(特技_斩将)))
    	{
    		pk::person@ person = pk::get_person(target.leader);
        if (ch::has_skill(person, 特技_强运)) return;
  			if (ch::has_skill(target, 特技_护卫) and !ch::has_skill(person, 特技_护卫)) return;
  			if (pk::is_in_screen(target.pos))
        {
          string death_msg = 死者台词[pk::rand(int(死者台词.length))];
          pk::say(pk::encode(death_msg), person, target);
        }
        pk::wait(1);
        pk::kill(person, pk::get_person(ch::who_has_skill(attacker, 特技_斩将)), target, null, 2);
        pk::play_se(3);
        pk::create_death_effect(target);
        pk::kill(target);
    	}
    }

    void func_毁坏(pk::force@ force, pk::unit@ attacker, pk::unit@ target)
    {
    	if (target !is null and ch::has_skill(attacker, 特技_毁坏) and target.weapon >= 兵器_冲车 and target.weapon <= 兵器_木兽 and pk::rand_bool(pk::core::skill_constant_value(特技_毁坏)))
    	{
  			if (pk::is_in_screen(target.pos))
        {
          pk::say(pk::encode('糟糕，攻城器械坏了'), pk::get_person(target.leader), target);
        }
        pk::change_weapon(target, 兵器_剑);
    	}
    }

    void func_纵火(pk::force@ force, pk::unit@ attacker, pk::unit@ target)
    {
      if (target !is null and ch::has_skill(attacker, 特技_纵火) and pk::rand_bool(pk::core::skill_constant_value(特技_纵火)))
      {
        if (pk::is_in_screen(target.pos))
        {
          pk::say(pk::encode('散开，快散开'), pk::get_person(target.leader), target);
        }
        pk::create_fire(target.pos, random(2), attacker);
      }
    }

    void func_苦肉(pk::force@ force, pk::unit@ attacker, pk::unit@ target)
    {
      if (target !is null and ch::has_skill(attacker, 特技_苦肉) and pk::rand_bool(pk::core::skill_constant_value(特技_苦肉)))
      {
        bool shoubyou = false;
        for (int i = 0; i < 3; i += 1)
        {
          pk::person@ person = pk::get_person(attacker.member[i]);
          if (person is null) break;
          if (person.shoubyou > 伤病_健康)
          {
            shoubyou = true;
            break;
          }
        }
        if (shoubyou and ch::set_status(target, attacker, 部队状态_混乱, 1, 0))
        {
          if (pk::is_in_screen(target.pos))
          {
            pk::say(pk::encode('不好，是苦肉计'), pk::get_person(target.leader), target);
          }
        }
      }
    }

    void func_魅惑(pk::force@ force, pk::unit@ attacker, pk::unit@ target)
    {
      if (target !is null and ch::has_skill(attacker, 特技_魅惑) and !pk::has_female_member(target) and pk::rand_bool(pk::core::skill_constant_value(特技_魅惑)))
      {
        pk::add_energy(target, -pk::core::skill_constant_value(特技_魅惑, 1), true);
        pk::person@ leader = pk::get_person(target.leader);
        string name = pk::decode(leader.azana.isEmpty() ? leader.mei : leader.azana);
        pk::say(pk::encode(pk::format("\x1b[1x{}\x1b[0x哥哥，看呆了吧", name)), pk::get_person(ch::who_has_skill(attacker, 特技_魅惑)), attacker);
      }
    }

    void func_击虚(pk::unit@ attacker, pk::unit@ target)
    {
      pk::person@ skill_person = pk::get_person(ch::who_has_skill(attacker, 特技_击虚));
      array<pk::point> rings = pk::range(target.get_pos(), 1, 1);
      int count = 0;
      for (int i = 0; i < int(rings.length); i++)
      {
        pk::unit@ dst = pk::get_unit(rings[i]);
        if (dst !is null and dst.get_force_id() == target.get_force_id() and pk::rand_bool(pk::core::skill_constant_value(特技_击虚)))
        {
          count += 1;
          ch::set_status(dst, attacker, 部队状态_混乱, 1, 0);
        }
      }
      if (count > 0) pk::say(pk::encode("兵之形，避实而击虚"), skill_person, attacker);
    }

    void func_反击(pk::unit@ attacker, pk::unit@ target)
    {
      if (pk::is_alive(attacker) and pk::rand_bool(pk::core::skill_constant_value(特技_反击)))
      {
        // pk::person@ skill_person = pk::get_person(ch::who_has_skill(target, 特技_反击));
        pk::person@ attacker_leader = pk::get_person(attacker.leader);
        if (ch::set_person_wound(attacker_leader, attacker_leader.shoubyou + 1, true, attacker))
        {
          pk::say(pk::encode("反击太强了，必须速速回城"), attacker_leader, attacker);
        }
      }
    }

    void func_伪退(pk::unit@ attacker, pk::unit@ target)
    {
      if (pk::is_alive(attacker))
      {
        pk::person@ person = pk::get_person(attacker.leader);
        ch::set_status(attacker, target, 部队状态_混乱, pk::core::skill_constant_value(特技_伪退), 0);
        pk::say(pk::encode('不好，中计了'), person, attacker);
      }
    }

    void func_激昂(pk::unit@ attacker)
    {
      if (pk::is_alive(attacker))
      {
        pk::add_energy(attacker, pk::core::skill_constant_value(特技_激昂), true);
        pk::say(pk::encode('哈哈哈\n剑锋所指，敌莫敢当'), pk::get_person(ch::who_has_skill(attacker, 特技_激昂)), attacker);
      }
    }

    void func_收拢(pk::unit@ target)
    {
      array<pk::point> rings = pk::range(target.get_pos(), 1, 2);
      int count = 0;
      for (int i = 0; i < int(rings.length); i++)
      {
        pk::unit@ dst = pk::get_unit(rings[i]);
        if (dst !is null and dst.get_force_id() != target.get_force_id() and ch::has_skill(dst, 特技_收拢))
        {
          pk::add_troops(dst, random(200, 300), true);
          pk::say(pk::encode('且扎营寨，击其懈怠'), pk::get_person(ch::who_has_skill(dst, 特技_收拢)), dst);
        }
      }
    }

    void func_引燃(pk::unit@ attacker, pk::unit@ target)
    {
      if (pk::is_alive(attacker))
      {
        array<pk::point> rings = pk::range(target.get_pos(), 1, 2);
        int count = 0;
        for (int i = 0; i < int(rings.length); i++)
        {
          pk::unit@ dst = pk::get_unit(rings[i]);
          if (dst !is null and pk::is_alive(dst) and dst.get_force_id() != attacker.get_force_id() and unit_list_id.find(dst.get_id()) < 0)
          {
            unit_list_id.insertLast(dst.get_id());
            pk::create_fire(rings[i], 1, attacker);
            count += 1;
          }
        }

        if (count > 0) pk::say(pk::encode('红莲灿世，燃尽苍穹'), pk::get_person(ch::who_has_skill(attacker, 特技_引燃)), attacker);
        unit_list_id.removeRange(0, unit_list_id.length);
      }
    }

    void func_势力城池(pk::force@ force)
    {
      for (int i = 0; i < 据点_末; i += 1)
      {
        pk::building@ building = pk::get_building(i);
        if (building.get_force_id() == force.get_id())
        {
          if (ch::has_skill(building, 特技_重镇) && ch::neibor_enemy_base_count(building, 1, false) >= 1)
          {
            int min_public_order = pk::core::skill_constant_value(特技_重镇);
            if (i >= 建筑_城市末)
            {
              auto base_t = ch::get_base_p(i);
              if (int(base_t.public_order) < int(min_public_order))
              {
                base_t.public_order = min_public_order;
                pk::history_log(building.pos, force.color, pk::encode(pk::format("\x1b[1x{}\x1b[0x由于\x1b[27x{}\x1b[0x的效果，治安变为\x1b[32x{}", pk::decode(pk::get_name(building)), '重镇', min_public_order)));
              }
            }
            else
            {
              pk::city@ city = pk::get_city(i);
              if (int(city.public_order) < int(min_public_order))
              {
                pk::set_public_order(city, min_public_order);
                pk::history_log(building.pos, force.color, pk::encode(pk::format("\x1b[1x{}\x1b[0x由于\x1b[27x{}\x1b[0x的效果，治安变为\x1b[32x{}", pk::decode(pk::get_name(building)), '重镇', min_public_order)));
              }
            }
          }
          int person_id = pk::get_taishu_id(building);
          if (pk::is_valid_person_id(person_id))
          {
            int hp = int(pk::get_person(person_id).stat[武将能力_政治] * 1.8f);
            hp = int(hp * (pk::has_tech(force, 技巧_木牛流马) ? 2.5f : 1));
            hp = int(hp * pk::core::skill_constant_value(特技_严防, 1) / 100);
            pk::add_hp(building, hp, true);
          }
        }
      }
    }
	}
	Main main;
}